package com.hzjq.fxlib.ui

import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.text.TextUtils
import android.view.KeyEvent
import android.view.WindowManager
import android.widget.TextView
import com.hzjq.core.Blast
import com.hzjq.core.BlastDelegate
import com.hzjq.core.bean.*
import com.hzjq.core.callback.Callback
import com.hzjq.core.callback.MainRunnable
import com.hzjq.core.callback.ProgressCallback
import com.hzjq.core.callback.ThreadRunnable
import com.hzjq.core.event.PioUnEnableEvent
import com.hzjq.fxlib.R
import com.hzjq.fxlib.callback.ChargeCallback
import com.hzjq.fxlib.callback.OnChargeClickListener
import com.hzjq.fxlib.event.LogEvent
import com.hzjq.fxlib.presenter.AbsViewPresenter
import com.hzjq.fxlib.presenter.RegisterFinishPresenter
import com.hzjq.fxlib.presenter.RegisterProgressPresenter
import com.hzjq.fxlib.presenter.RegisterScanPresenter
import com.lxj.xpopup.XPopup
import com.lxj.xpopup.core.BasePopupView
import com.lxj.xpopup.interfaces.SimpleCallback
import com.wxl.common.AppContext
import com.wxl.common.base.AbsActivity
import com.wxl.common.util.Toll
import io.reactivex.Observable
import io.reactivex.ObservableEmitter
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.functions.Consumer
import io.reactivex.schedulers.Schedulers
import kotlinx.android.synthetic.main.activity_register_cap_layout.*
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import java.util.*

class RegisterCapActivity : AbsActivity() {

    companion object {
        private var chargeClick: OnChargeClickListener?=null
        fun start(context: Context, caps: ArrayList<CapEntity>, chargeClick: OnChargeClickListener) {
            if(caps.size > BlastDelegate.getDelegate().getMaxSupportCapCount()){
                Toll.toll("雷管超过最大组网负载数")
                return
            }
            BlastDelegate.getDelegate().setMaxSupportCapCount(caps.size)
            Companion.chargeClick = chargeClick
            val intent = Intent(context, RegisterCapActivity::class.java)
            intent.putExtra("caps", caps)
            context.startActivity(intent)
        }
    }

    private val caps = arrayListOf<CapEntity>()
    private val registerResultCaps = arrayListOf<ErrorCapEntity>()
    private val meetCaps = arrayListOf<ErrorCapEntity>()
    private val missCaps = arrayListOf<ErrorCapEntity>()
    private var disposable: Disposable? = null
    private var maxDelay = 0L
    private var presenters = arrayListOf<AbsViewPresenter>()
    private lateinit var mRegisterScanPresenter: RegisterScanPresenter
    private var position = 0
    private var errorCapCount = 0
    private var warnPopupView : BasePopupView? = null
    private val ecs = arrayListOf<ErrorCapEntity>()

    override fun getCreateContentViewId(): Int {
        return R.layout.activity_register_cap_layout
    }

    override fun onCreateViewChanged() {
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        AppContext.appContext.init(application, true)
        caps.clear()
        caps.addAll(intent.getSerializableExtra("caps") as ArrayList<CapEntity>)

        findMaxDelay()

        findViewById<TextView>(R.id.titleTextView).textSize = 24f


        mRegisterScanPresenter = RegisterScanPresenter(registerCapContainer)
        presenters.add(mRegisterScanPresenter)
        presenters.add(RegisterProgressPresenter(registerCapContainer))
        presenters.add(RegisterFinishPresenter(registerCapContainer))

        mRegisterScanPresenter.show()

        registerRetryBtn.isEnabled = false
        registerRetryBtn.isClickable = false
        registerRetryBtn.setOnClickListener {
            registerRetryBtn.isEnabled = false
            registerRetryBtn.isClickable = false
            onRetryClick()
        }

        registerChargeBtn.isEnabled = false
        registerChargeBtn.isClickable = false
        registerChargeBtn.setOnClickListener {
            registerChargeBtn.isEnabled = false
            registerChargeBtn.isClickable = false
            onChargeClick()
        }
        registerRetryCancel.setOnClickListener {
            registerRetryCancel.isEnabled = false
            onShowBack()
        }
    }


    private fun findMaxDelay() {
        BlastDelegate.getDelegate()
            .post(object : ThreadRunnable<Long> {
                override fun run(e: ObservableEmitter<Long>) {
                    caps.forEach {
                        if (maxDelay < it.delay) {
                            maxDelay = it.delay
                        }
                    }
                    e.onNext(maxDelay)
                }
            }, object : MainRunnable<Long> {
                override fun run(t: Long) {
                    onRegisterCap()
                }
            })
    }

    private fun onRegisterReset(){
        registerChargeBtn.isEnabled = false
        registerChargeBtn.isClickable = false
        registerRetryBtn.isEnabled = false
        registerRetryBtn.isClickable = false
        EventBus.getDefault().post(LogEvent("开始组网"))
        errorCapCount = 0
        registerResultCaps.clear()
        mRegisterScanPresenter.showAction("正在下传雷管信息")
        mRegisterScanPresenter.notifyScanCountChanged(0,0,0,0,false)
        meetCaps.clear()
        missCaps.clear()
        ecs.clear()
    }


    private fun onRegisterCap() {
        onRegisterReset()
        Blast.getInstance().quickRegister()
            .onQuickRegister(caps, maxDelay, object : ProgressCallback<CapProgressEntity> {
                override fun onError(errorCode: ErrorResult) {
                    registerRetryBtn.isEnabled = true
                    registerRetryBtn.isClickable = true
                    presenters[position].showAction(errorCode.errorAction)
                }

                override fun onProgressChanged(progress: Int, total: Int, action: String) {
                    onRegisterProgressChanged(progress, total, action)
                }

                override fun onResult(t: CapProgressEntity) {
                    if (t.isEnd) {
                        EventBus.getDefault().post(LogEvent("组网成功"))
                        convertOkCap()
                    }
                    registerCapDy.text = "电压:"+t.mVoltage.toString() + "V"
                    registerCapDl.text = "电流:"+t.mElectric.toString() + "mA"
                }

                override fun onRetryCountChanged(retryCount: Int, action: String) {
                   // presenters[position].showAction("${action}($retryCount)...")
                }

            }, Consumer<ErrorReadCapEntity> {
                if(it.caps[it.caps.size - 1].isScanEnd) {
                    EventBus.getDefault().post(LogEvent("组网失败"))
                    convertErrorCap(it)
                }
            })
    }



    private fun onRegisterProgressChanged(progress: Int, total: Int, action: String){
        if(action.startsWith("已检测到") && action.endsWith("发雷管")){
            val scanCount = action.replace("已检测到","").replace("发雷管","").toInt()
            mRegisterScanPresenter.notifyScanCountChanged(scanCount,0,0,0,false)
            mRegisterScanPresenter.notifyProgressBar(action,progress)
            presenters[1].hide()
        }
        if(TextUtils.equals(action,"正在检查雷管密码")){
            position = 0
            presenters[1].hide()
        }
        if(TextUtils.equals(action,"正在进入授权模式")){
            position = 1
            presenters[position].show()
        }
        if(action.contains("授权") || action.contains("校时")) {
            presenters[position].notifyProgressBar("正在校验", progress)
        }
    }


    private fun onRetryClick() {
        position = 0
        presenters[1].hide()
        mRegisterScanPresenter.show()
        onRegisterCap()
    }


    private fun onChargeClick() {
        chargeClick!!.onChargeClick(this, object : ChargeCallback {
            override fun go() {
                presenters[1].hide()
                Blast.getInstance().quickRegister().cancel()
                ChargeActivity.start(this@RegisterCapActivity, registerResultCaps, maxDelay)
                finish()
            }

            override fun enable() {
                registerChargeBtn.isEnabled = true
                registerChargeBtn.isClickable = true
            }
        })
    }


    private fun showCaps(isEnd:Boolean) {
        registerRetryBtn.isEnabled = true
        registerRetryBtn.isClickable = true
        mRegisterScanPresenter.notifyScanCountChanged(errorCapCount,errorCapCount - ecs.size,meetCaps.size,ecs.size - meetCaps.size,isEnd)
        if(isEnd){
//            val ecs = arrayListOf<ErrorCapEntity>()
//            ecs.addAll(missCaps)
//            ecs.addAll(meetCaps)
            mRegisterScanPresenter.setErrorCap(ecs)
        }
    }


    @SuppressLint("CheckResult")
    private fun convertOkCap() {
        Observable.create<Boolean> {
            registerResultCaps.clear()
            caps.forEach {
                val e= ErrorCapEntity()
                e.errorCode = 0
                e.cap = it
                registerResultCaps.add(e)
            }
            it.onNext(true)
        }.subscribeOn(Schedulers.newThread())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe {
                registerChargeBtn.isEnabled = true
                registerChargeBtn.isClickable = true
                position = 2
                presenters[position].show()
                presenters[position].showAction("校验成功")
                (presenters[2] as RegisterFinishPresenter).showCapCount(caps.size)
                (presenters[2] as RegisterFinishPresenter).setClickCallback(Runnable {
                    registerChargeBtn.performClick()
                })
            }

    }


    private fun convertErrorCap(result:ErrorReadCapEntity) {
        disposable?.dispose()
        meetCaps.clear()
        missCaps.clear()
        ecs.addAll(result.errors)
        disposable = Observable.create<MutableList<ErrorCapEntity>>() {
            errorCapCount = result.caps.size
            result.errors.forEach {
                if(it.errorCode == 1 && !meetCaps.contains(it)){//多接
                    meetCaps.add(it)
                }
                if(it.errorCode == 2 && !missCaps.contains(it)){
                    missCaps.add(it)
                }
            }
            it.onNext(registerResultCaps)
        }.subscribeOn(Schedulers.newThread())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe {
                position = 0
                presenters[position].show()
                showCaps(result.caps[result.caps.size - 1].isScanEnd)
            }
    }


    override fun getPageTitle(): String {
        return "起爆网络检测"
    }



    override fun onBackPressed() {
        onShowBack()
    }

    override fun onBackClick(): Boolean {
        onShowBack()
        return false
    }

    override fun onDestroy() {
        super.onDestroy()
        presenters[1].hide()
    }

    private fun onShowBack() {
        if (warnPopupView != null && warnPopupView!!.isShow) {
            return
        }
        warnPopupView=  XPopup.Builder(this)
            .setPopupCallback(object : SimpleCallback(){
                override fun onDismiss() {
                    registerRetryCancel.isEnabled = true
                }
            })
            .hasShadowBg(false)
            .asConfirm("提示", "是否终止当前操作？", {
                exitRegister()
            }, {
                registerRetryCancel.isEnabled = true
            }).show()
    }


    private fun exitRegister() {
        val show = XPopup.Builder(this)
            .hasShadowBg(false)
            .asLoading("正在退出,请等待...")
            .show()

        Blast.getInstance().quickRegister()
            .exitQuickRegister(object : Callback<Boolean> {
                override fun onError(errorCode: ErrorResult) {
                    show.dismiss()
                    Toll.toll("退出失败")
                }

                override fun onResult(t: Boolean) {
                    show.dismiss()
                    if (t) {
                        finish()
                    } else {
                        Toll.toll("退出失败")
                    }
                }

                override fun onRetryCountChanged(retryCount: Int, action: String) {

                }
            })

    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onPioUnEnableEvent(e: PioUnEnableEvent){
        showPioUnEnablePop(this)
    }

    override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
        if(keyCode == KeyEvent.KEYCODE_BACK){
            onShowBack()
            return true
        }
        return presenters[position].onKeyDown(keyCode, event)
    }
}